package com.hitqz.robot.dispatch.netty.strategy.zhiqingDispather;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.hitqz.robot.api.business.entity.RobotEntity;
import com.hitqz.robot.api.dispatch.protocol.dto.RobotCmdNavDto;
import com.hitqz.robot.api.dispatch.protocol.dto.RobotDto;
import com.hitqz.robot.biz.service.RobotService;
import com.hitqz.robot.dispatch.netty.NettyMessageHandler;
import com.hitqz.robot.dispatch.netty.decoder.Server2RobotDecoder;
import com.hitqz.robot.dispatch.netty.encoder.Server2RobotEncoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LinearRing;
import org.locationtech.jts.geom.Polygon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;
import org.locationtech.jts.geom.*;
/**
 * @author xupkun
 * @date 2023/7/14
 */
@Slf4j
@Component
public class DispatchCommandLineRunner  {

    @Autowired
    private RobotService robotService;

    //阻塞区域半径长度
    @Value("${blockRadio:1.8}")
    private Double blockRadio;

    @Value("${notBlockRadio:2}")
    private Double notBlockRadio;


    //@PostConstruct
    public void run() throws Exception {


        log.info("阻塞区域半径长度{}", blockRadio);


        List<RobotEntity> list = robotService.query().list();



        for (RobotEntity robotEntity : list) {
            RobotDto target = new RobotDto();
            BeanUtil.copyProperties(robotEntity, target);
            if (robotEntity.getRobotSn().equals("ZQ1")) {


                GeometryFactory geometryFactory = new GeometryFactory();

                // 定义目标矩形
                Coordinate[] rectCoords = new Coordinate[]{
                        new Coordinate(4.0, 7.8),
                        new Coordinate(4.0, 9.2),
                        new Coordinate(10.0, 9.2),
                        new Coordinate(10.0, 7.8),
                        new Coordinate(4.0, 7.8)  // 闭合
                };
                LinearRing rectRing = geometryFactory.createLinearRing(rectCoords);
                Polygon rectPolygon = geometryFactory.createPolygon(rectRing);
                rectPolygon.buffer(notBlockRadio);

                ApplyThread applyThread = new ApplyThread(target, new BlockedContext(blockRadio,rectPolygon));
                new Thread(applyThread).start();


            }else if (robotEntity.getRobotSn().equals("ZQ2")) {
                ApplyThread applyThread = new ApplyThread(target, new BlockedContext(blockRadio,null));
                new Thread(applyThread).start();
            }
        }
    }

    public static void bind(Integer port) {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            log.info("正在启动服务端netty通讯端口成功{}", port);
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .childOption(ChannelOption.TCP_NODELAY, true)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_RCVBUF, 1024 * 1024)
                    .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024))
                    .childHandler(
                            new ChannelInitializer<Channel>() {
                                @Override
                                protected void initChannel(Channel channel) throws Exception {
                                    channel.pipeline().addLast(new LengthFieldBasedFrameDecoder(
                                            1024 * 1024 + 46, // 最大帧长度（1 MB 数据 ）
                                            42,        // 长度字段的偏移量
                                            4,         // 长度字段的字节数
                                            0,         // 长度调整
                                            2         // 初始偏移量 跳过0xEB90
                                    ));
                                    channel.pipeline().addLast(new Server2RobotDecoder());
                                    channel.pipeline().addLast(new Server2RobotEncoder());
                                    channel.pipeline().addLast(new NettyMessageHandler());
                                }
                            }
                    );
            // 端口绑定
            ChannelFuture f = bootstrap.bind(port).sync();
            Channel channel = f.channel();
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            log.error("启动 netty 失败:" + e.getMessage());
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

}
